package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/validator/v10"
)

type SignUpParam struct {
	Age        int    `json:"age" binding:"ageable,required"`
	Name       string `json:"name" binding:"required"`
	Email      string `json:"email" `
	Password   string `json:"password" `
	RePassword string `json:"re_password"`
}

// 自定义验证错误信息的方法

func (s *SignUpParam) GetError(err validator.ValidationErrors) string {
	// 这里 索引要对应模型类的名称字段
	for _, v := range err {
		fmt.Printf("%#v, %v", v.Tag(), v.Tag())
		switch v.Tag() {
		case "ageable":
			return "agebale error"
		case "required":
			return "缺少必传参数"
		}
	}
	return "参数错误"
}

//validator v9以上写法
func ageaBle(fl validator.FieldLevel) bool {
	if age, ok := fl.Field().Interface().(int); ok {
		fmt.Println(age)
		if age < 0 {
			return false
		}
	}
	return true
}

//validator v8写法
// func ageaBle(
// 	v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
// 	field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
// ) bool {
// 	if age, ok := field.Interface().(uint8); ok {
// 		fmt.Println(age)
// 		if age < 0 {
// 			return false
// 		}
// 	}
// 	return true
// }

func main() {
	r := gin.Default()

	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
		v.RegisterValidation("ageable", ageaBle)
	}

	r.POST("/signup", func(c *gin.Context) {
		var u SignUpParam
		if err := c.ShouldBind(&u); err != nil {
			c.JSON(http.StatusOK, gin.H{
				"msg": u.GetError(err.(validator.ValidationErrors)),
			})
			return
		}
		// 保存入库等业务逻辑代码...

		c.JSON(http.StatusOK, "success")
	})

	_ = r.Run(":8999")
}
